#ifndef SPA_QUERY_EVALUATOR_H
#define SPA_QUERY_EVALUATOR_H

#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <iostream>
#include "ShortcutTable.h"
#include "ProcTable.h"
#include "VarTable.h"
#include "QueryTypes.h"
#include "Pattern.h"
#include "ParentHandle.h"
#include "FollowsHandle.h"
#include "UsesHandle.h"
#include "ModifiesHandle.h"
#include "NextHandle.h"
#include "CallsHandle.h"
#include "AffectsHandle.h"
#include "SiblingHandle.h"
#include "AffectsBIPHandle.h"
#include "NextBIPHandle.h"
#include "PKB.h"
#include "QueryPreprocessor.h"

class QueryEvaluator
{
	private:
		Pattern _pattern;
		QueryPreprocessor* _querypreprocessor;
		ParentHandle* _parenthandle;
		FollowsHandle* _followshandle;
		UsesHandle* _useshandle;
		ModifiesHandle* _modifieshandle;
		NextHandle* _nexthandle;
		CallsHandle* _callshandle;
		AffectsHandle* _affectshandle;
		SiblingHandle* _siblinghandle;
		AffectsBIPHandle* _affectsbiphandle;
		NextBIPHandle* _nextbiphandle;
		vector<vector<int>> comb;
		vector<int> status;

		vector<vector<string>> Evaluate_Now( query_tree& _query_tree );
		vector<vector<string>> Evaluate_Now2( query_tree& _query_tree );
		void updates( int, int, int, int, int );
		void combinations( vector<vector<int>>, int, vector<int> );
		vector<int> RemoveDuplicates( vector<int> );
		vector<int> SetIntersection( vector<int>, vector<int> );
		string RemoveAttribute( string );
		vector<int> GetAllProgramLine();
		vector<int> GetAllStatement();
		vector<int> GetAllAssign();
		vector<int> GetAllCall();
		vector<int> GetAllIf();
		vector<int> GetAllWhile();
		vector<int> GetAllConstant();
		vector<int> GetAllProcIndex();
		vector<int> GetAllVarIndex();
		int GetNumOfEntities(query_relation);

	public:
		QueryEvaluator();
		~QueryEvaluator();

		void SetQueryPreprocessor( QueryPreprocessor* preprocessor );
		list<string> Evaluate( query_tree& _query_tree );
};

#endif